package com.gopay.bis.service.bank.impl.micro;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.manager.bank.micro.MicroPayManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.MicroPayConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.wechat.micro.req.MicroPayReqMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroQueryReqMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroRefundQueryReqMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroRefundReqMsg;
import com.gopay.common.domain.bank.wechat.micro.req.MicroReverseReqMsg;
import com.gopay.common.domain.bank.wechat.micro.res.MicroPayResMsg;
import com.gopay.common.domain.bank.wechat.micro.res.MicroQueryResMsg;
import com.gopay.common.domain.bank.wechat.micro.res.MicroRefundQueryResMsg;
import com.gopay.common.domain.bank.wechat.micro.res.MicroRefundResMsg;
import com.gopay.common.domain.bank.wechat.micro.res.MicroReverseResMsg;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.MicroPayInteractRemoteService;


/**
 * 小额免密支付接口实现
 * 
 * @ClassName: MicroPayServiceImpl
 * @author w_jiqing
 * @date 2017年5月25日 下午2:40:12
 */
public class MicroPayServiceImpl implements MicroPayInteractRemoteService {

    @Resource(name = "microPayManager")
    private MicroPayManager microPayManager;

    @Override
    public Result pay(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroPayReqMsg message = new MicroPayReqMsg();
            BeanUtils.copyProperties(base, message);
            MicroPayResMsg res = (MicroPayResMsg) microPayManager.payment(message);
            result.setDefaultModel(res.isSuccess());
            result.setModel("res", res);
            Map<String, String> param = new HashMap<String, String>();
            if (res.isSuccess() && MicroPayConstants.MICRO_RESULT_CODE_SUCCESS.equals(res.getResult_code())
                    && MicroPayConstants.MICRO_PAY_RESULT_SUCCESS.equals(res.getPay_result())) {
                // 支付成功
                param.put("orderId", base.getOrderId());
                param.put("amt", new BigDecimal(res.getTotal_fee()).divide(new BigDecimal(100)).toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "00");
                param.put("retCode", "00");
                param.put("retMsg", "验签成功");
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setOrderStatus(true);
            } else if(res.isSuccess()&& "USERPAYING".equals(res.getResult_code())){
                //需要用户输入支付密码
                param.put("orderId", base.getOrderId());
                param.put("amt", base.getAmount().toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "02");
                param.put("retCode", "01");
                String errorMessage = StringUtils.isEmpty(res.getErr_msg()) ? res.getMessage() : res.getErr_msg();
                param.put("retMsg", errorMessage);
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setErrorMsg(errorMessage);
                result.setOrderStatus(false);
            }else {
                param.put("orderId", base.getOrderId());
                param.put("amt", base.getAmount().toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "01");
                param.put("retCode", "01");
                String errorMessage = StringUtils.isEmpty(res.getErr_msg()) ? res.getMessage() : res.getErr_msg();
                param.put("retMsg", errorMessage);
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setErrorMsg(errorMessage);
                result.setOrderStatus(false);
            }
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E7025);
        }
        return result;
    }

    
    
    @Override
    public Result reverse(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroReverseReqMsg message = new MicroReverseReqMsg();
            BeanUtils.copyProperties(base, message);
            Map<String, String> param = new HashMap<String, String>();
            MicroReverseResMsg res = (MicroReverseResMsg) microPayManager.reverse(message);
            result.setDefaultModel(res.isSuccess());
            if (res.isSuccess()&& MicroPayConstants.MICRO_RESULT_CODE_SUCCESS.equals(res.getResult_code())) {                
                param.put("orderId", message.getOrderId());
                param.put("amt", base.getAmount().toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "00");
                param.put("retCode", "00");
                param.put("retMsg", "验签成功");
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setOrderStatus(true);
            } else {
                param.put("orderId", message.getOrderId());
                param.put("amt", base.getAmount().toString());
                param.put("cardType", "Unknown");
                param.put("notifyNum", "1");
                param.put("payStatus", "01");
                param.put("retCode", "01");
                // 记录数据库失败信息 add by zhengxue 20170313
                String errorMessage = StringUtils.isEmpty(res.getErr_msg()) ? res.getMessage() : res.getErr_msg();
                param.put("retMsg", errorMessage);
                param.put("isFront", String.valueOf(false));
                result.setModel("isNotifyCashier", param);
                result.setSuccess(true);
                result.setOrderStatus(false);
            }
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            // 需新增错误码
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E1181);
        }
        return result;
    }

    @Override
    public Result orderQuery(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroQueryReqMsg message = new MicroQueryReqMsg();
            BeanUtils.copyProperties(base, message);
            MicroQueryResMsg res = (MicroQueryResMsg) microPayManager.orderQuery(message);
            result.setDefaultModel(res);
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
        }
        return result;
    }

    @Override
    public Result refund(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroRefundReqMsg message = new MicroRefundReqMsg();
            BeanUtils.copyProperties(base, message);
            MicroRefundResMsg res = (MicroRefundResMsg) microPayManager.refund(message);
            result.setDefaultModel(res);
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E6087);
        }
        return result;
    }

    @Override
    public Result refundQuery(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroRefundQueryReqMsg message = new MicroRefundQueryReqMsg();
            BeanUtils.copyProperties(base, message);
            MicroRefundQueryResMsg res = (MicroRefundQueryResMsg) microPayManager.refundQuery(message);
            result.setDefaultModel(res);
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
        }
        return result;
    }



    @Override
    public Result reverseQuery(BaseMessage base) throws GopayException {
        Result result = new Result(false);
        try {
            MicroQueryReqMsg message = new MicroQueryReqMsg();
            BeanUtils.copyProperties(base, message);
            MicroQueryResMsg res = (MicroQueryResMsg) microPayManager.orderQuery(message);
            result.setDefaultModel(res);
            result.setSuccess(true);
        } catch (GopayException e) {
            BankLogUtils.printServiceImplExceptionLog(e);
            result.setResultCode(e.getErrCode());
        } catch (Exception ex) {
            BankLogUtils.printServiceImplExceptionLog(ex);
            result.setResultCode(ProcCodeConstants.PROC_CODE_100E7027);
        }
        return result;
    }




    

}
